using System;
using System.Net.Sockets;
using System.Net;

namespace XcoAppSpaces.Transport.Sockets
{
	static class SocketExtensions
	{
		public static void Send(this Socket socket, byte[] msg, Action<object, SocketAsyncEventArgs> continuationAction)
		{
			var evt = new SocketAsyncEventArgs();
			evt.SetBuffer(msg, 0, msg.Length);

			evt.Completed += (s, e) => continuationAction(s, e);
			if (!socket.SendAsync(evt)) //if false is returned here, the operation was already completed synchronously and the event will not be triggered
				continuationAction(socket, evt);
		}

		public static void Connect(this Socket socket, string remoteAddress, Action<object, SocketAsyncEventArgs> continuationAction)
		{
			var remoteAddressParts = remoteAddress.Split(':');
			var hostname = remoteAddressParts[0];
			var port = int.Parse(remoteAddressParts[1]);

			var evt = new SocketAsyncEventArgs();
			evt.RemoteEndPoint = new DnsEndPoint(hostname, port);

			evt.Completed += (s, e) => continuationAction(s,e);
			if (!socket.ConnectAsync(evt))  //if false is returned here, the operation was already completed synchronously and the event will not be triggered
				continuationAction(socket, evt);
		}

		public static void Receive(this Socket socket, Action<object, SocketAsyncEventArgs> continuationAction)
		{
			Receive(socket, 0, continuationAction);
		}

		public static void Receive(this Socket socket, int bufferSize, Action<object, SocketAsyncEventArgs> continuationAction)
		{
			var evt = new SocketAsyncEventArgs();
			var transferBuffer = new byte[bufferSize > 0 ? bufferSize : socket.ReceiveBufferSize];
			evt.SetBuffer(transferBuffer, 0, transferBuffer.Length);

			evt.Completed += (s, e) => continuationAction(s, e);
			if (!socket.ReceiveAsync(evt)) //if false is returned here, the operation was already completed synchronously and the event will not be triggered
				continuationAction(socket, evt);
		}
	}
}
